# coding:utf-8
from PySide6.QtCore import Qt
from PySide6.QtGui import QColor, QPainter, QLinearGradient
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from qfluentwidgets import ClickableSlider, FluentStyleSheet, isDarkTheme, FluentIcon, CaptionLabel, HollowHandleStyle, \
    themeColor
from qfluentwidgets.multimedia import MediaPlayerBase, MediaPlayer
from qfluentwidgets.multimedia.media_play_bar import PlayButton, VolumeButton, MediaPlayBarButton


class PlayBar(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.player = None  # type: MediaPlayer

        self.vBoxLayout = QVBoxLayout(self)
        self.timeLayout = QHBoxLayout()
        self.buttonLayout = QHBoxLayout()
        self.leftButtonContainer = QWidget()
        self.centerButtonContainer = QWidget()
        self.rightButtonContainer = QWidget()
        self.leftButtonLayout = QHBoxLayout(self.leftButtonContainer)
        self.centerButtonLayout = QHBoxLayout(self.centerButtonContainer)
        self.rightButtonLayout = QHBoxLayout(self.rightButtonContainer)

        self.playButton = PlayButton(self)
        self.volumeButton = VolumeButton(self)
        self.progressSlider = ClickableSlider(Qt.Orientation.Horizontal, self)
        self.skipBackButton = MediaPlayBarButton(FluentIcon.SKIP_BACK, self)
        self.skipForwardButton = MediaPlayBarButton(FluentIcon.SKIP_FORWARD, self)
        self.fullScreenButton = MediaPlayBarButton(FluentIcon.FULL_SCREEN, self)
        self.downloadButton = MediaPlayBarButton(FluentIcon.DOWNLOAD, self)

        self.currentTimeLabel = CaptionLabel('00:00', self)
        self.remainTimeLabel = CaptionLabel('00:00', self)

        self.__initWidgets()

    def __initWidgets(self):
        # set the style of slider
        color = themeColor()
        style = HollowHandleStyle({
            "groove.height": 4,
            "sub-page.color": color,
            "add-page.color": QColor(255, 255, 255, 50),
            "handle.color": color,
            "handle.ring-width": 2,
            "handle.hollow-radius": 10,
            "handle.margin": 0
        })
        self.progressSlider.setStyle(style)
        self.progressSlider.setFixedHeight(25)
        FluentStyleSheet.MEDIA_PLAYER.apply(self)

        self.setFixedHeight(150)
        self.vBoxLayout.setSpacing(6)
        self.vBoxLayout.setContentsMargins(20, 20, 20, 20)

        self.vBoxLayout.addLayout(self.timeLayout)
        self.timeLayout.setContentsMargins(0, 0, 0, 0)
        self.timeLayout.setSpacing(15)
        self.timeLayout.addWidget(self.currentTimeLabel, 0, Qt.AlignmentFlag.AlignLeft)
        self.timeLayout.addWidget(self.progressSlider, 1, Qt.AlignmentFlag.AlignTop)
        self.timeLayout.addWidget(self.remainTimeLabel, 0, Qt.AlignmentFlag.AlignRight)

        self.vBoxLayout.addStretch(1)
        self.vBoxLayout.addLayout(self.buttonLayout, 1)
        self.buttonLayout.setContentsMargins(0, 0, 0, 0)
        self.leftButtonLayout.setContentsMargins(4, 0, 0, 0)
        self.centerButtonLayout.setContentsMargins(0, 0, 0, 0)
        self.rightButtonLayout.setContentsMargins(0, 0, 4, 0)

        self.leftButtonLayout.addWidget(self.volumeButton, 0, Qt.AlignmentFlag.AlignLeft)
        self.centerButtonLayout.addWidget(self.skipBackButton)
        self.centerButtonLayout.addWidget(self.playButton)
        self.centerButtonLayout.addWidget(self.skipForwardButton)

        self.rightButtonLayout.addWidget(self.fullScreenButton)
        self.rightButtonLayout.addWidget(self.downloadButton)

        self.buttonLayout.addWidget(self.leftButtonContainer, 0, Qt.AlignmentFlag.AlignLeft)
        self.buttonLayout.addWidget(self.centerButtonContainer, 0, Qt.AlignmentFlag.AlignHCenter)
        self.buttonLayout.addWidget(self.rightButtonContainer, 0, Qt.AlignmentFlag.AlignRight)

        self.setMediaPlayer(MediaPlayer(self))

        self.skipBackButton.setToolTip('后退')
        self.skipForwardButton.setToolTip('前进')
        self.playButton.setToolTip('播放/暂停')
        self.volumeButton.setToolTip('音量')
        self.fullScreenButton.setToolTip('全屏/退出全屏')
        self.downloadButton.setToolTip('下载')

        self.skipBackButton.clicked.connect(lambda: self.skipBack(10000))
        self.skipForwardButton.clicked.connect(lambda: self.skipForward(30000))
        self.playButton.clicked.connect(self.togglePlayState)

    def setMediaPlayer(self, player: MediaPlayerBase):
        """ set media player """
        self.player = player

        self.player.durationChanged.connect(self.progressSlider.setMaximum)
        self.player.positionChanged.connect(self._onPositionChanged)
        self.player.mediaStatusChanged.connect(self._onMediaStatusChanged)
        self.player.volumeChanged.connect(self.volumeButton.setVolume)
        self.player.mutedChanged.connect(self.volumeButton.setMuted)

        # don't use valueChanged, otherwise the sound will be interupted
        self.progressSlider.sliderMoved.connect(self.player.setPosition)
        self.progressSlider.clicked.connect(self.player.setPosition)
        self.volumeButton.volumeChanged.connect(self.player.setVolume)
        self.volumeButton.mutedChanged.connect(self.player.setMuted)

        self.player.setVolume(30)

    def play(self):
        self.player.play()

    def pause(self):
        self.player.pause()

    def stop(self):
        self.player.stop()

    def setVolume(self, volume: int):
        """ Sets the volume of player """
        self.player.setVolume(volume)

    def setPosition(self, position: int):
        """ Sets the position of media in ms """
        self.player.setPosition(position)

    def _onPositionChanged(self, position: int):
        self.progressSlider.setValue(position)
        self.currentTimeLabel.setText(self._formatTime(position))
        self.remainTimeLabel.setText(self._formatTime(self.player.duration() - position))

    def _onMediaStatusChanged(self, status):
        self.playButton.setPlay(self.player.isPlaying())

    def togglePlayState(self):
        """ toggle the play state of media player """
        if self.player.isPlaying():
            self.player.pause()
        else:
            self.player.play()

        self.playButton.setPlay(self.player.isPlaying())

    def paintEvent(self, e):
        """ paint play bar """
        painter = QPainter(self)
        if isDarkTheme():
            linear = QLinearGradient(0, 0, 0, self.height())
            linear.setColorAt(0, QColor(0, 0, 0, 0))
            linear.setColorAt(1, QColor(0, 0, 0, 204))
            painter.setBrush(linear)
        else:
            linear = QLinearGradient(0, 0, 0, self.height())
            linear.setColorAt(0, QColor(255, 255, 255, 0))
            linear.setColorAt(1, QColor(255, 255, 255, 204))
            painter.setBrush(linear)
        painter.setPen(Qt.PenStyle.NoPen)
        painter.drawRect(self.rect())
        painter.end()

    def skipBack(self, ms: int):
        """ Back up for specified milliseconds """
        self.player.setPosition(self.player.position() - ms)

    def skipForward(self, ms: int):
        """ Fast forward specified milliseconds """
        self.player.setPosition(self.player.position() + ms)

    def _formatTime(self, time: int):
        time = int(time / 1000)
        s = time % 60
        m = int(time / 60) % 60
        h = int(time / 3600)
        if h > 0:
            return f'{h}:{m:02}:{s:02}'
        else:
            return f'{m:02}:{s:02}'
